/**
 * Copyright (C), 2020-2020,贵州铭明网络科技有限公司
 * FileName: UserRealm
 * Author:   杨朝湖
 * Date:     2020/11/27 15:34
 * Description:
 * History:
 * <author>          <time>          <version>          <desc>
 * 作者姓名           修改时间           版本号              描述
 */
package com.mm.shiro;

import com.mm.mapper.AdministratorInfoMapper;
import com.mm.pojo.AdministratorInfo;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.util.ByteSource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import tk.mybatis.mapper.entity.Example;

import javax.annotation.Resource;

/**
 * 〈权限逻辑认证〉<br>
 * 〈〉
 *
 * @author Gym
 * @create 2020/11/27
 * @since 1.0.0
 */
public class MyShiroRealm extends AuthorizingRealm {
    private static final Logger logger = LoggerFactory.getLogger(MyShiroRealm.class);
    @Resource
    private AdministratorInfoMapper administratorInfoMapper;
    /**
     * 授权管理
     *
     * @param principals
     * @return
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        logger.info("执行逻辑授权操作");
        //给资源进行授权管理
        SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
        //获取当前登录的用户信息
        Subject subject = SecurityUtils.getSubject();
        //示例，获取管理员的信息，根据具体用户信息而定
        AdministratorInfo administratorInfo = (AdministratorInfo) subject.getPrincipal();
        //获取管理员的权限字符信息,在数据库中查询
        //添加权限到资源库中
        simpleAuthorizationInfo.addStringPermission(administratorInfo.getAdminId());
        return simpleAuthorizationInfo;
    }

    /**
     * 登录管理
     *
     * @param authenticationToken
     * @return
     * @throws AuthenticationException
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        logger.info("执行登录授权操作");
        UsernamePasswordToken token = (UsernamePasswordToken) authenticationToken;
        //获取登录的用户名
        String adminName = token.getUsername();
        //数据库中获取用户信息
        Example example = new Example(AdministratorInfo.class);
        example.createCriteria().andEqualTo("adminName", adminName);
        AdministratorInfo administratorInfo = administratorInfoMapper.selectOneByExample(example);

        return new SimpleAuthenticationInfo(
                // 这里传入的是user对象，比对的是用户名，直接传入用户名也没错，但是在授权部分就需要自己重新从数据库里取权限
                administratorInfo,
                // 密码
                administratorInfo.getAdminPassword(),
                // salt = 用户加密盐
                ByteSource.Util.bytes(administratorInfo.getAdminKey()),
                // realm name
                getName()
        );
    }
}